package AlexDB.Command;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@CommandTypeAttribute("list")
public class ListCommand extends BaseCommand<HashMap<String,List<Object>>> implements IDbCommandType
{
    List<Object> keyMap;
    ICommandOperationEvent event;

    public Object commandExecute(Object[] args) throws Exception {
        var command = args[1].toString();
        var key = args[2].toString();
        
        map = getDataBaseMap();
        if(map == null)
        {
            map = new HashMap<String,List<Object>>();
            putToDataMap();
        }

        keyMap = map.get(key);
        if(keyMap == null)
        {
            keyMap = new LinkedList<Object>();
            map.put(key, keyMap);
        }

        Method thisMethods = getInvokeMethod(command);
        var toMethodsArgs =  Arrays.asList(args).subList(3, args.length);
        return thisMethods.invoke(this,toMethodsArgs.toArray());
    }

    @CommandOperationAttribute("lpush")
    Object leftPush(Object arg)
    {
        keyMap.add(0,arg);
        if(event!=null)event.invoke();
        return arg;
    }
    
    @CommandOperationAttribute("rpush")
    Object rightPush(Object arg)
    {
        keyMap.add(arg);
        if(event!=null)event.invoke();
        return arg;
    }

    @CommandOperationAttribute("lpop")
    Object leftPop()
    {
       if(event!=null)event.invoke();
       return keyMap.remove(0);
    }

    @CommandOperationAttribute("rpop")
    Object rightPop()
    {
        if(keyMap.size() <= 0)
            return null;
        if(event!=null)event.invoke();
        return keyMap.remove(keyMap.size()-1);
    }

    @CommandOperationAttribute("range")
    List<Object> range(Object start,Object stop)
    {
        var startIndex = Integer.parseInt(start.toString());
        var startStop = Integer.parseInt(stop.toString());
        if(event!=null)event.invoke();
        return keyMap.subList( startIndex <= 0 ? 0:startIndex ,startStop > keyMap.size() ? keyMap.size() : startStop );
    }

    @CommandOperationAttribute("get")
    Object[] GetAll()
    {
        if(event!=null)event.invoke();
        return keyMap.toArray();
    }

}
